// ****************************************************************************
//  list  version:  1.0    date: 2020-12-14    author: windspc
//  ---------------------------------------------------------------------------
//
//  ---------------------------------------------------------------------------
//  Copyright (C) 2020 PengChao(pengc@hitrobotgroup.com) - All Rights Reserved
// ****************************************************************************
//
// ****************************************************************************
#ifndef LIST_HPP
#define LIST_HPP

#include <atomic>
static int MAXLISTSIZE = 1024;

template<typename DataType>
struct DataNode{
    DataNode* next;
    DataType  data;
};

template<typename DataType>
class List{
public:
    List();
    ~List();

    bool Init(int size = MAXLISTSIZE);
    bool PushData(DataType const & data);
    bool PopFront();
    DataNode<DataType>* GetFront();
    bool IsEmpty();

    void Clear();

    int GetNumber();

private:

    bool PushBack(DataNode<DataType>* node);

private:

    DataNode<DataType>* list_;

    DataNode<DataType>* header_;
    DataNode<DataType>* tailer_;
    DataNode<DataType>* cur_;
    int size_;
    std::atomic<int> used_;
};

template<typename DataType>
List<DataType>::List()
    : list_(nullptr)
    , header_(nullptr)
    , tailer_(nullptr)
    , cur_(nullptr)
    , size_(0)
{

}

template<typename DataType>
List<DataType>::~List() {
    if(list_ != nullptr){
        delete[] list_;
        size_ = 0;
    }
}

template<typename DataType>
bool List<DataType>::Init(int size) {
    if(size <= 2){
        return false;
    }

    list_ = new DataNode<DataType>[size];
    for(int i = 0; i < size; ++ i){
        if(i == size - 1){
            list_[i].next = nullptr;
        } else {
            list_[i].next = &list_[i + 1];
        }
    }

    header_ = &list_[0];
    tailer_ = &list_[size - 1];
    cur_ = &list_[0];

    size_ = size;
    used_ = 0;
    return true;
}

template<typename DataType>
int List<DataType>::GetNumber(){
    return used_;
}

template<typename DataType>
bool List<DataType>::PushData(DataType const & data) {
    // 1. 判断当前是否已经到达最后的位置
    if(cur_ == tailer_){
        return false;
    }

    cur_->data = data;
    cur_ = cur_->next;
    ++ used_;
    return true;
}

template<typename DataType>
bool List<DataType>::PushBack(DataNode<DataType>* node) {
    if(!node || !tailer_){
        return false;
    }

    tailer_->next = node;
    node->next = nullptr;
    tailer_ = node;
    -- used_;
    return true;
}

template<typename DataType>
bool List<DataType>::PopFront() {
    // cur_后面的数据是无效数据
    if(!header_ || !(header_->next) || header_ == cur_)
        return false;

    DataNode<DataType>* temp = header_;
    header_ = header_->next;
    bool ret = PushBack(temp);
    return ret;
}

template<typename DataType>
void List<DataType>::Clear()
{
    cur_ = header_;
    used_ = 0;
}

template<typename DataType>
DataNode<DataType>* List<DataType>::GetFront()
{
    // cur_后面的数据是无效数据
    if (header_ == cur_) {
        return nullptr;
    }
    return header_;
}

template<typename DataType>
bool List<DataType>::IsEmpty(){
    if (header_ == cur_) {
        return true;
    }
    return false;
}

#endif // LIST_HPP
